package org.lambda.list;

import com.alibaba.fastjson.JSON;

import java.text.MessageFormat;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class ListReduceDemo {

    public static void main(String[] args) throws Exception {
        List<Integer> list = Stream.of(1, 2, 3).collect(Collectors.toList());

        System.out.print(list.stream().reduce((result, item) -> result * item).get());
        System.out.println("\n--------");

        System.out.print(list.stream().sequential().reduce(3, (result, item) -> result + item));
        System.out.println("\n--------");

        System.out.print(list.stream().sequential().reduce(3, (result, item) -> result + item, (result, item) -> result * item));
        System.out.println("\n--------");

        System.out.print(list.stream().parallel().reduce(3, (result, item) -> result + item, (result, item) -> result * item));
        System.out.println("\n--------");

        System.out.print(list.stream().parallel().reduce(3, (result, item) -> result + item, (result, item) -> result + item));
        System.out.println("\n--------");

        System.out.print(list.stream().parallel().reduce(3, (result, item) -> result, (result, item) -> result + item));
        System.out.println("\n--------");

        final int[] time = new int[]{0, 0, 0, 0};
        Integer r1 = list.stream().sequential().reduce(3,
                (result, item) -> {
                    time[0] += 1;
                    System.out.println(MessageFormat.format("[sequential]-time:{0}-item:{1}", JSON.toJSONString(time), JSON.toJSONString(item)));
                    result = result + item;
                    return result;
                }, (result, item) -> {
                    time[1] += 1;
                    System.out.println(MessageFormat.format("[parallel]-time:{0}-item:{1}", JSON.toJSONString(time), JSON.toJSONString(item)));
                    result = result * item;
                    return result;
                });
        System.out.println(r1);
        System.out.println("--------");

        Integer r2 = list.stream().parallel().reduce(3,
                (result, item) -> {
                    time[2] += 1;
                    System.out.println(MessageFormat.format("[sequential]-time:{0}-item:{1}", JSON.toJSONString(time), JSON.toJSONString(item)));
                    result = result + item;
                    return result;
                }, (result, item) -> {
                    time[3] += 1;
                    System.out.println(MessageFormat.format("[parallel]-time:{0}-item:{1}", JSON.toJSONString(time), JSON.toJSONString(item)));
                    result = result * item;
                    return result;
                });
        System.out.println(r2);
        System.out.println("--------");

        Thread.sleep(1000);
    }
}
